#include "bsp_tm1640.h"


static uint8_t num_t[10] =
{ 
	0x3f, //0b00111111,
	0x06,//0b00000110,
	0x5b,//0b01011011,
	0x4f,//0b01001111,
	0x66,//0b01100110,
	0x6D,//0b01101101,
	0x7D,//0b01111101,
	0x07,//0b00000111,
	0x7F,//0b01111111,
	0x67//0b01100111
};
static uint8_t tm_value[16] = {
	0xff
};
static uint8_t disMode[3] = { 0x8F, 0x88, 0x80 };//最亮/最暗/关掉
static uint8_t useMode = 0;
/********  TM1640 GPIO 配置 *************************/
  
//*************************************  
// 函数名称：_Nopt  
// 函数功能：延时函数  
// 入口参数：延时时间  
// 出口参数：无  
//***************************************/  
void Nop1640(uint16_t T_Dly)  
{     
	while (T_Dly--) __NOP();
	return ;  
}  
//****************************************  
// 函数名称：TM1640Start  
// 函数功能：TM1640起始信号  
// 入口参数：无  
// 出口参数：无  
//***************************************/  
void TM1640Start(void)  
{   
	TM1640DAT_HING;  
	Nop1640(VT_DLYNOP);  
	TM1640SLK_HING;  
	Nop1640(VT_DLY1640);  
	TM1640DAT_LOW;  
	Nop1640(VT_DLY1640);  
	TM1640SLK_LOW;  
	Nop1640(VT_DLY1640);  
}  
//*************************************  
// 函数名称：TM1640Stop  
// 函数功能：TM1640结束信号  
// 入口参数：无  
// 出口参数：无  
//***************************************/  
void TM1640Stop(void)  
{  
	TM1640DAT_LOW;  
	Nop1640(VT_DLYNOP);  
	TM1640SLK_HING;  
	Nop1640(VT_DLY1640);  
	TM1640DAT_HING;  
	Nop1640(VT_DLY1640);  
	TM1640SLK_LOW;  
	Nop1640(VT_DLY1640);  
          
}
/***
 ***刷新函数
 ***
 ****/
void TM1640_Refresh(void)
{
	TM1640Start();//数据写模式设置  
	TM1640WriteByte(SET_DATA_INSRT);//数据命令设置 地址自动加1  
	TM1640Stop(); 
	TM1640_SendData(0, tm_value, 16);
	TM1640Start();//数据写模式设置  
	TM1640WriteByte(disMode[useMode]);//显示关控制   
	TM1640Stop();
}
void TM1640_UpdateNum(uint8_t num /*1-4*/, uint8_t value/*0-9*/)
{
	switch (num)
	{
	case NUM_TL://gird4
		if (value > 9) break;
		tm_value[3] = num_t[value];
		break;
	case NUM_TR://grid5
		if (value > 9) break;
		tm_value[5] = num_t[value];
		break;
	case NUM_SL://grid6
		if (value > 9) break;
		tm_value[4] = num_t[value];
		break;
	case NUM_SR://grid7
		if (value > 9) break;
		tm_value[6] = num_t[value];
		break;
	case NUM_LIGHT:
		if (value > 3) break;
		useMode = value;
		break;
	case NUM_LL:
		if (value > 9) break;
		tm_value[0] = num_t[value];
		break;
	case NUM_LM:
		if (value > 9) break;
		tm_value[1] = num_t[value];
		break;
	case NUM_LR:
		if (value > 9) break;
		tm_value[2] = num_t[value];
		break;
	case NUM_MAX:/**全更新**/
		for (uint8_t i = 0; i < sizeof(num_t); i++)
		{
			tm_value[i] = value;
		}
		break;
	default:
		break;
	}
}
//最开始的初始化
void TM1640_InitFirst(void)
{
	uint8_t az[16] = { 0 };
	///设置数据指令，地址自动加一
	TM1640Start();//数据写模式设置  
	TM1640WriteByte(SET_DATA_ORDER);
	TM1640Stop();//数据写模式设置  
	///设置显示地址
	TM1640_SendData(0x00, az, sizeof(az));
	///清空显示RAM
	///显示控制指令
	TM1640_Init(1);
}
//*************************************  
// 函数名称：TM1640WriteByte  
// 函数功能：TM1640写一字节数据  
// 入口参数：要写的数据  
// 出口参数：无  
//***************************************/  
void TM1640WriteByte(uint8_t date)  
{  
	uint8_t i;  
	uint8_t Tmp;  
          
	Tmp = date;  
          
	TM1640DAT_LOW;  
	Nop1640(VT_DLYNOP);  
	TM1640SLK_LOW;  
          
	for (i = 0;i < 8;i++)  
	{  
		TM1640SLK_LOW;  
		Nop1640(VT_DLYNOP);  
		if (Tmp & 0x01)  
		{  
			TM1640DAT_HING;  
			Nop1640(VT_DLY1640);  
		}  
		else  
		{  
			TM1640DAT_LOW;  
			Nop1640(VT_DLY1640);  
		}  
		TM1640SLK_HING;  
		Tmp = Tmp >> 1;  
	}  
          
	TM1640SLK_LOW;  
	Nop1640(VT_DLYNOP);  
	TM1640DAT_LOW;  
}  
//*************************************  
// 函数名称：TM1640_Init  
// 函数功能：TM1640设备初始化  
// 入口参数：0 1 代表 显示关 显示开  
// 出口参数：无  
//***************************************/  
void TM1640_Init(uint8_t InValue)    
{  
	TM1640DAT_HING;  
	Nop1640(VT_DLYNOP);                 
	TM1640SLK_HING;  
          
	if (InValue == DSP1640_DIS) //显示关  
		{  
			TM1640Start();//数据写模式设置  
			TM1640WriteByte(SET_DSP1640_DIS);//显示关控制   
			TM1640Stop();         
		}  
	else  
	{  
		TM1640Start();//数据写模式设置  
		TM1640WriteByte(SET_DATA_INSRT);//数据命令设置 地址自动加1  
		TM1640Stop();  
                  
		TM1640Start(); //显示亮度设置  
		TM1640WriteByte(SET_DISPLAY); //显示命令控制  脉冲宽度14/16       
		TM1640Stop();  
	}  
}  
//*************************************  
// 函数名称：TM1640_SendData  
// 函数功能：发送显示缓存  
// 入口参数：1640要写数据的起始地址  
//           显示数据缓存的起始地址 数据长度  
// 出口参数：无  
//***************************************/  
void TM1640_SendData(uint8_t Addr1640, uint8_t *a, uint8_t DataLong)  
{  
	uint8_t i;    
          
	TM1640Start();  
	TM1640WriteByte(0xC0 & Addr1640); //设置起始地址  
          
	for(i = 0 ; i < DataLong ; i++)  
	{  
		TM1640WriteByte(a[i]);   
	}  
          
	TM1640Stop();   
}
/**
 ** 测试用
 **
 ***/
void TM1640_example(void)
{
	TM1640_InitFirst();
	TM1640_UpdateNum(NUM_MAX, 0xff); //全亮
	TM1640_Refresh();
	HAL_Delay(1000);
	TM1640_UpdateNum(NUM_MAX, 0x00); //全亮
	TM1640_Refresh();
	HAL_Delay(1000);
}
